import { componentTypeFileName } from "../components/Form/base/options";
import moment from "moment";
import { convertType, money2Fixed } from "../utils/util";
import _ from "lodash";
import axios from "axios";

/* 改变控件类型的处理函数 */
export const changeControlTypes = function (type, formData, index) {
  // 根据类型获取对应的组件文件名
  const fileName = componentTypeFileName[type];
  // 动态导入组件配置
  const { defaultData, dataTypeOptions } = require(
    "@/components/Form/formViews/" + fileName + ".vue"
  );

  // 从传入的formData中解构需要的字段
  const {
    name,
    dataIndex,
    dataType,
    wrapperCol,
    required,
    validateCondition,
    explain,
    hide,
    disabled,
    placeholder,
  } = formData || {};

  // 获取选中的索引
  const selectIndex = index ?? this.dataObj.selectIndex;

  // 先用默认数据重置表单数据
  this.dataObj.pageData[selectIndex].formData = defaultData();

  // 如果有传入formData,则更新相关字段
  if (formData) {
    const pageData = this.dataObj.pageData[selectIndex];
    // 更新类型
    pageData.type = type;
    // 更新名称(分割线组件特殊处理)
    const finalName = type === "divider" ? "" : name;
    pageData.name = finalName;
    pageData.formData.name = finalName;

    // 更新表单数据的其他字段
    Object.assign(pageData.formData, {
      dataIndex,
      // 检查并设置数据类型
      dataType: dataTypeOptions.some((option) => option.value === dataType)
        ? dataType
        : dataTypeOptions[0].value,
      required,
      explain,
      wrapperCol,
      disabled,
      hide,
      placeholder,
      validateCondition, // 校验规则配置
    });
  }
};
/* 根据选择的数据视图类型更改表单数据 */
export const changeDataViewSel = function (value) {
  if (value === "手填") {
    this.formData.dataIndex = "";
  } else {
    const {
      controlType,
      condition,
      groupId,
      aggregateId,
      queryKey,
      groupType,
    } = this.dataObj.queryGroupList.find(
      (item) => item.groupId + " " + item.queryKey === value
    );
    this.formData.dataIndex = queryKey;
    this.formData.controlType = controlType;
    this.formData.groupId = groupId;
    this.formData.aggregateId = aggregateId;
    this.formData.groupType = groupType;
    if (["range"].includes(controlType)) {
      // 范围查询
      this.formData.condition[0].queryKey = condition[0].queryKey;
      this.formData.condition[1].queryKey = condition[1].queryKey;
    }
  }
};
// 赋值多个字段
export const changeAssignmentList = function (array) {
  this.formData.queryAssignments = {}; // 查询条件需要多个值
  array.forEach((value) => {
    const { controlType, condition, queryKey, groupId, aggregateId } =
      this.dataObj.queryGroupList.find(
        (item) => item.groupId + " " + item.queryKey === value
      );
    if (controlType === "range") {
      // 范围查询
      this.formData.queryAssignments[value] = {
        aggregateId,
        groupId,
        queryKey,
        condition: [
          { queryKey: condition[0].queryKey },
          { queryKey: condition[1].queryKey },
        ],
      };
    } else {
      this.formData.queryAssignments[value] = {
        aggregateId,
        groupId,
        queryKey,
        condition: [{ queryKey: queryKey }],
      };
    }
  });
};

/* 解决弹窗报错设置焦点 */
export const setFocusToFirstFocusableElement = function () {
  this.$nextTick(() => {
    const modalContent = document.querySelector(".ant-modal-content");
    if (modalContent) {
      const focusableElements = modalContent.querySelectorAll(
        'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
      );
      if (focusableElements.length > 0) {
        focusableElements[0].focus();
      }
    }
  });
};
// 解析搜索UI条件数据源OPTS
export const requestSearchDataSource = async function (
  checkedFirstOption = true,
  checkVisibility = false
) {
  // 如果没有 this.searchUi 或者 没有 this.searchUi.pageData，则直接返回已解决的 Promise
  if (!this.searchUi || !this.searchUi.pageData) return Promise.resolve();

  // 准备发送请求的 promise 数组
  const requestPromises = this.searchUi.pageData
    // 增加显示判断条件
    .filter((item) => {
      const isVisible = checkVisibility ? this.doRule(item) : true;
      return isVisible && item.formData.dataSource === "dataSource";
    })
    .map(async (item) => {
      const {
        formData: {
          dataSourceId: dataId,
          dataOptionField,
          dataCondition,
          dataType,
        },
      } = item;
      // 展示字段 dataShowFieIds是兼容字段，dataShowFields是实际字段
      const dataShowFields = item.formData.dataShowFields;
      // 如果 dataId 为空，则直接返回已解决的 Promise，不进行请求
      if (!dataId) return;

      let value = {};
      if (dataCondition && dataCondition.length) {
        value = dataCondition.reduce((acc, cc) => {
          if (!acc[cc.groupId]) acc[cc.groupId] = {};
          acc[cc.groupId][cc.columnKey] = cc.defaultTheValue;
          return acc;
        }, {});
      }

      try {
        const result = await this.$http.post(`/datasource/dataExec`, {
          dataId,
          valueMap: value,
        });

        const processTree = (treeData) => {
          function processNode(node) {
            let key = "";
            if (Array.isArray(dataShowFields)) {
              key = dataShowFields
                .map((key) => {
                  if (
                    columnTypeMap[key]?.columnType === "timestamp" &&
                    columnTypeMap[key]?.typeFormat
                  ) {
                    return moment(node[key]).format(
                      columnTypeMap[key]?.typeFormat
                    );
                  }
                  return node[key];
                })
                .join("_");
            }
            node.key = key;
            node.value = convertType(node[dataOptionField], dataType);

            if (node.children && node.children.length > 0) {
              node.children.forEach((child) => processNode(child));
            }
          }

          treeData.forEach((node) => processNode(node));
          return treeData;
        };

        const { columnTypeMap, resultPage } = result.data;
        const opts = processTree(resultPage.rows) || [];
        const orderIndex = this.searchUi.pageData.findIndex(
          (e) => e.cid === item.cid
        );
        if (_.has(this.searchUi.pageData[orderIndex], "formData")) {
          const { groupIds, level } = this.$store.getters.userInfo;
          if (level !== "三级" || (groupIds && groupIds.includes(1))) {
            opts.unshift({ key: "全部", value: "" });
          }
          _.assign(this.searchUi.pageData[orderIndex].formData, { opts });
          if (
            checkedFirstOption &&
            item.formData.opts &&
            item.formData.opts.length
          ) {
            // 默认选中第一个
            this.$set(
              this.queryParam,
              item.formData.dataIndex,
              item.formData.opts[0].value
            );
          }
        }
      } catch (error) {
        console.error("Error during request:", error);
      }
    });

  // 等待所有请求完成
  await Promise.all(requestPromises);

  // 返回一个已经解决的 Promise 表明所有请求已完成
  return Promise.resolve();
};

export const fetchSearchDataSourceData = async function (targetItem) {
  const { dataIndex } = targetItem?.formData || {};
  const _formList = dataIndex
    ? this.searchUi.pageData.filter((item) =>
        item.formData.dataCondition?.some((condition) =>
          condition?.tableQueryGroupAddDTOList?.some(
            (group) => group.dataIndex === dataIndex
          )
        )
      )
    : this.searchUi.pageData;

  for (const item of _formList) {
    if (
      !_.isEmpty(item.formData.dataCondition) &&
      item.formData.dataSource !== "alone"
    ) {
      try {
        this.source && this.source.cancel();
        this.source = axios.CancelToken.source();

        const value = processDataCondition(
          item.formData.dataCondition,
          this.queryParam
        );
        const { dataSourceId } = item.formData;
        const params = { valueMap: value, dataId: dataSourceId };
        const result = await this.$http.post("/datasource/dataExec", params, {
          cancelToken: this.source.token,
        });

        const { dataOptionField, dataType, dataShowFields } = item.formData;
        const { columnTypeMap } = result.data;
        const opts =
          result.data.resultPage.rows?.map((row) => {
            let key = "";
            if (Array.isArray(dataShowFields)) {
              key = dataShowFields
                ?.map((key) => {
                  if (
                    columnTypeMap[key]?.columnType === "timestamp" &&
                    columnTypeMap[key]?.typeFormat
                  ) {
                    return moment(row[key]).format(
                      columnTypeMap[key]?.typeFormat
                    );
                  }
                  return row[key];
                })
                .join("_");
            }
            return {
              ...row,
              key,
              value: convertType(row[dataOptionField], dataType),
            };
          }) || [];

        const orderIndex = this.searchUi.pageData.findIndex(
          (e) => e.cid === item.cid
        );
        const { groupIds, level } = this.$store.getters.userInfo;
        if (level !== "三级" || (groupIds && groupIds.includes(1))) {
          opts.unshift({
            key:
              "全部" + (this.searchUi.pageData[orderIndex].formData.name || ""),
            value: "",
          });
        }
        _.assign(this.searchUi.pageData[orderIndex].formData, { opts });
        if (opts.length) {
          this.$set(this.queryParam, item.formData.dataIndex, opts[0].value);
        } else {
          this.$set(this.queryParam, item.formData.dataIndex, "");
        }
        item.formData.searchLoading = false;
      } catch (e) {
        console.error("数据源请求失败", e);
        item.formData.searchLoading = false;
      }
    }
  }
};

export const getChartDataDeal = function (data, config, exeRawData) {
  const { yName, xName, xField, yField, chartType, gridsList = [] } = config;
  const regex = /\$\{.*?\}/;
  let result;
  if (chartType === "Gather") {
    result = {};
    gridsList.forEach((item) => {
      const { gridName, gridValue, gridUnit } = item;

      try {
        // 确保 data 对象存在
        if (!data) throw new Error("Data object is not defined.");

        let count;
        if (regex.test(gridValue)) {
          // 使用 doEvl 函数前确保 gridValue 已正确替换
          const evaluatedValue = gridValue.replace(
            /\$\{([^}]+)\}/g,
            (match, key) => {
              if (data[key] === undefined)
                throw new Error(`Key ${key} not found in data.`);
              return data[key];
            }
          );
          count = doEvl(evaluatedValue);
        } else {
          count = gridValue; // 假设 gridValue 是可以直接赋值的数字或字符串
        }

        result[gridName] = {
          count: count,
          unit: gridUnit, // 提供单位的默认值
          config: item,
        };
      } catch (error) {
        console.error(`处理 ${gridName} 时发生错误:`, error.message);
        // 可选：记录错误信息、设置错误标识或执行其他错误处理逻辑
        result[gridName] = {
          count: null, // 或者一个表明错误状态的值
          unit: gridUnit,
          config: item,
          error: error.message, // 记录错误信息以便后续排查
        };
      }
    });
  } else {
    // 其它图表
    result = [];
    if (!data?.length || chartType === "Gantt") {
      // 无数据或甘特图直接返回
      return data || [];
    }
    data.forEach((item, pIndex) => {
      const xTypeFormat = _.get(exeRawData?.columnTypeMap, xField)?.typeFormat;
      if (xTypeFormat) {
        _.set(item, xField, moment(+_.get(item, xField)).format(xTypeFormat));
      } else {
        _.set(
          item,
          xField,
          isNaN(+_.get(item, xField))
            ? _.get(item, xField)
            : +_.get(item, xField)
        );
      }
      const YTypeFormat = _.get(exeRawData?.columnTypeMap, yField)?.typeFormat;

      if (YTypeFormat) {
        _.set(item, yField, moment(+_.get(item, yField)).format(YTypeFormat));
      } else {
        _.set(
          item,
          yField,
          isNaN(+_.get(item, yField))
            ? _.get(item, yField)
            : +_.get(item, yField)
        );
      }
      if (gridsList.length === 0) {
        result.push({
          [xName]: regex.test(xField)
            ? _.get(item, xField.replace(/\${(.*?)}/, "$1"))
            : item[xField],
          [yName]: regex.test(yField)
            ? _.get(item, yField.replace(/\${(.*?)}/, "$1"))
            : item[yField],
        });
      } else {
        gridsList.forEach((grid) => {
          const { gridName, gridValue } = grid;
          result.push({
            type: regex.test(gridName)
              ? _.get(item, gridName.replace(/\${(.*?)}/, "$1"))
              : gridName,
            [xName]: regex.test(xField)
              ? _.get(item, xField.replace(/\${(.*?)}/, "$1"))
              : item[xField],
            [yName]: doEvl(
              gridValue.replace(/\$\{([^}]+)\}/g, (match, key) => item[key])
            ),
          });
        });
      }
    });
  }

  return result;
};

export const doEvl = function (value) {
  // eslint-disable-next-line no-eval
  return money2Fixed(eval(value)) || 0;
};

/**
 * 处理 dataCondition 数据，将其转换为一个对象，该对象的键是 groupId 和 columnKey 的组合，
 * 值是 defaultTheValue。如果存在 between 属性，则会进一步处理。
 *
 * @param {Array} dataCondition - 包含需要处理的数据项数组。
 * @param {Object} form - 表单对象，表单数据。
 * @returns {Object} - 返回一个新对象，其中每个 groupId 对应一个子对象，
 *                     而每个子对象则包含了由 columnKey 映射的 defaultTheValue。
 */
export const processDataCondition = function (dataCondition, form = {}) {
  /**
   * 辅助函数：处理单个数据项并返回一个新的对象。
   *
   * @param {Object} item - 单个数据项。
   * @param {boolean} [isBetween=false] - 标志是否正在处理 'between' 子项。
   * @returns {Object} - 返回处理后的对象。
   */
  const processItem = (item, isBetween = false) => ({
    columnKey: item.queryKey || item.columnKey, // 根据情况选择正确的 columnKey
    dataIndex: item.dataIndex,
    defaultTheValue: item.defaultTheValue,
    groupId: item.groupId,
  });

  /**
   * 辅助函数：处理包含 'between' 属性的项。
   *
   * @param {Object} item - 单个数据项。
   * @returns {Array} - 返回一个由处理后的对象组成的数组。
   */
  const handleBetween = (item) => {
    if (_.isArray(item.between) && item.between.length) {
      // 如果 'between' 是一个非空数组，则映射其每一个元素
      return item.between.map((subItem) => processItem(subItem, true));
    }
    // 否则，直接处理当前项
    return [processItem(item)];
  };

  // 使用 flatMap 遍历 dataCondition 数组，并根据是否存在 'tableQueryGroupAddDTOList' 属性分别处理
  const keys = (dataCondition || []).flatMap((item) =>
    _.has(item, "tableQueryGroupAddDTOList")
      ? item.tableQueryGroupAddDTOList.flatMap(handleBetween)
      : [processItem(item)]
  );
  // 使用 reduce 方法生成最终的对象结构
  const value = keys.reduce(
    (acc, { groupId, columnKey, defaultTheValue = "", dataIndex }) => {
      // 确保 acc 中存在对应的 groupId 子对象
      acc[groupId] = acc[groupId] || {};
      // 将 columnKey 和 defaultTheValue 添加到对应的 groupId 下
      acc[groupId][columnKey] = form[dataIndex] || defaultTheValue;
      return acc;
    },
    {}
  );

  return value; // 返回处理后的结果
};

/**
 * 解析字段配置，生成过滤表达式字符串
 * @param {Array} fieldConfigs 字段配置数组，例如 this.showRuleConfig.fieldConfig
 * @returns {string} 过滤表达式字符串
 */
export const parseShowRulesToStr = function (fieldConfigs) {
  if (!_.isArray(fieldConfigs)) {
    return "";
  }
  const length = fieldConfigs.length;
  const regex = /\$\{.*?\}/;
  let str = "";
  fieldConfigs.forEach((item, index) => {
    const { field, fieldValue, logical, fieldValueType } = item;
    // 检查field是否为变量格式并处理
    const recordPrefix = regex.test(field) ? 'globalData["' : 'record["';
    const processedField = regex.test(field)
      ? field.replace(/\${(.*?)}/, "$1")
      : field;

    if (fieldValueType === "notEmpty") {
      // 不为空
      str +=
        recordPrefix +
        processedField +
        '"]' +
        (index === length - 1 ? "" : logical);
    } else if (fieldValueType === "unequal") {
      // 不等于
      str +=
        recordPrefix +
        processedField +
        '"]' +
        ("!='" + fieldValue + "'") +
        (index === length - 1 ? "" : logical);
    } else if (fieldValueType === "jt") {
      // 大于
      str +=
        recordPrefix +
        processedField +
        '"]' +
        (">" + fieldValue) +
        (index === length - 1 ? "" : logical);
    } else if (fieldValueType === "lt") {
      // 小于
      str +=
        recordPrefix +
        processedField +
        '"]' +
        ("<" + fieldValue) +
        (index === length - 1 ? "" : logical);
    } else {
      // 检查 fieldValue 是否为日期范围快捷选项
      if (fieldValue === "today") {
        const today = moment().format("YYYY-MM-DD");
        str +=
          recordPrefix +
          processedField +
          '"]' +
          ("=='" + today + "'") +
          (index === length - 1 ? "" : logical);
      } else if (fieldValue === "last3Days") {
        const start = moment().format("YYYY-MM-DD");
        const end = moment().add(3, "days").format("YYYY-MM-DD");
        str +=
          recordPrefix +
          processedField +
          '"]' +
          (">='" + start + "'") +
          "&&" +
          (recordPrefix + processedField + '"]') +
          ("<='" + end + "'") +
          (index === length - 1 ? "" : logical);
      } else if (fieldValue === "last7Days") {
        const start = moment().format("YYYY-MM-DD");
        const end = moment().add(7, "days").format("YYYY-MM-DD");
        str +=
          recordPrefix +
          processedField +
          '"]' +
          (">='" + start + "'") +
          "&&" +
          (recordPrefix + processedField + '"]') +
          ("<='" + end + "'") +
          (index === length - 1 ? "" : logical);
      } else {
        str +=
          recordPrefix +
          processedField +
          '"]' +
          ("=='" + fieldValue + "'") +
          (index === length - 1 ? "" : logical);
      }
    }
  });
  return str;
};

export const shouldHighlight = function (formData, compareValue) {
  // 将输入值转换为可比较的类型，假设都是数字类型
  const { highlightType, highlightValue, listStyleShow } = formData;
  if (listStyleShow !== "highlight") {
    return false;
  }
  const numCompareValue = parseFloat(compareValue);
  const numHighlightValue = parseFloat(highlightValue);

  switch (highlightType) {
    case "gt": // 大于
      return numCompareValue > numHighlightValue;
    case "lt": // 小于
      return numCompareValue < numHighlightValue;
    case "eq": // 等于
      return numCompareValue === numHighlightValue;
    case "ne": // 不等于
      return numCompareValue !== numHighlightValue;
    case "gte": // 大于等于
      return numCompareValue >= numHighlightValue;
    case "lte": // 小于等于
      return numCompareValue <= numHighlightValue;
    default:
      return false;
  }
};
